package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.domain.TOrderInfo;
import com.ruoyi.business.domain.TPayChannel;
import com.ruoyi.business.domain.TRecipientInfo;
import com.ruoyi.business.response.ResponseData;
import com.ruoyi.business.service.BasePayment;
import com.ruoyi.business.service.ChargeService;
import com.ruoyi.business.service.ITPayChannelService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.HttpUtils;
import com.ruoyi.common.utils.MD5Util;
import com.ruoyi.common.utils.SignUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service("commonPayService")
public class CommonPayServiceImpl extends BasePayment {


    @Resource
    private ChargeService chargeService;

    @Resource
    private ISysConfigService configService;

    @Resource
    private ITPayChannelService payChannelService;


    @Override
    public JSONObject createPayOrder(TOrderInfo orderInfo) throws Exception {
        JSONObject jsonObject = new JSONObject();
        TRecipientInfo userRecipientInfo = userRecipientService.selectTRecipientInfoById(orderInfo.getRecipientId());
        String callBackIpAddress = configService.selectConfigByKey("sys.bussine.callBackIpAddress");
        String payGateway = configService.selectConfigByKey("sys.bussine.payGateway");
        try {
            String requestParam = userRecipientInfo.getAccountJson();
            JSONObject reqObj = JSONObject.parseObject(userRecipientInfo.getAccountJson());
            JSONObject rsCfgObj = JSONObject.parseObject(userRecipientInfo.getReturnJson());
            JSONObject rerutnObj = new JSONObject();
            logger.info("COMMON请求参数：{}", reqObj);

            //提交请求地
            String AuthorizationURL = rsCfgObj.getString("reqUrl").replace("0x99ng", callBackIpAddress);
            //商户号
            String merchantId = userRecipientInfo.getChannelAccount();
            //秘钥获取路由商户编码
            String apiKey = rsCfgObj.getString("apiKey");
            logger.info("paymentOrder：{}", JSONObject.toJSONString(orderInfo));

            String orderTimeMillis = String.valueOf(System.currentTimeMillis());
            String dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            String dateTime_ = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            requestParam = requestParam.replace("0x99fenamount", orderInfo.getMoney() + "");
            requestParam = requestParam.replace("0x99amount", orderInfo.getMoney()/100 + "");
            requestParam = requestParam.replace("0x992amount", new BigDecimal(orderInfo.getMoney()/100).setScale(2) + "");
            String signType = rsCfgObj.getString("signType");
            String sign = "";
            String pay_notifyurl = "";
            String isNeedNg = rsCfgObj.getString("isNeedNg");

            TPayChannel payChannel = payChannelService.selectTPayChannelByCode(orderInfo.getChannel());

            pay_notifyurl = payGateway + "/notify/callback/v2/" + payChannel.getAliasName().toLowerCase() + "/" + orderInfo.getId();

            requestParam = requestParam.replace("0x99merchantOrderCode", orderInfo.getOutTradeNo());
            requestParam = requestParam.replace("0x99apiMerchant", merchantId);
            requestParam = requestParam.replace("0x99orderCode", orderInfo.getId()+"");
            requestParam = requestParam.replace("0x99apiKey", apiKey);
            requestParam = requestParam.replace("0x99notifyurl", pay_notifyurl);
//            requestParam = requestParam.replace("0x99customeOrder", paymentOrder.getMerOrderCode());
            requestParam = requestParam.replace("0x99orderTime", dateTime);
            requestParam = requestParam.replace("0x99MillisOrderTime", orderTimeMillis);
            requestParam = requestParam.replace("0x9910MillisOrderTime", orderTimeMillis.substring(0, 10));
            Map<String, String> map = JSON.parseObject(requestParam, Map.class);
            logger.info("COMMONz支付请求：{}", JSONObject.toJSONString(map));
            String signKey = rsCfgObj.getString("signKey");
            String paramLowType = rsCfgObj.getString("paramLowType");
            if (signType.equalsIgnoreCase("MD5") || signType.equalsIgnoreCase("SHA1")) {
                String requestNoSign = rsCfgObj.getString("requestNoSign");
                Map<String, String> signMap = new HashMap<>(map);
                logger.info("不参与验签的参数：" + requestNoSign);
                if (StringUtils.isNotBlank(requestNoSign)) {
                    String[] nosigns = requestNoSign.split("#");
                    for (int i = 0; i < nosigns.length; i++) {
                        signMap.remove(nosigns[i]);
                    }
                }
                String signRule = rsCfgObj.getString("signRule");
                logger.info("验签类型：" + signRule);
                if (signRule.equalsIgnoreCase("nomal")) {
                    StringBuilder buf = new StringBuilder("");
                    SignUtils.buildPayParams(buf, signMap, false, paramLowType);
                    String preStr = buf.toString();
                    logger.info("参数排序==>待验签数据:" + preStr);
                    if (signType.equalsIgnoreCase("MD5")) {
                        sign = MD5Util.stringMD5(preStr +"&key=" + apiKey);
                    }
                    map.put(signKey, sign);
                }
                /**else if (signRule.equalsIgnoreCase("customize")) {
                    JSONObject customRuleObj = JSONObject.parseObject(tRealChannelConfig.getCustomRule());
                    String perStr = customRuleObj.getString("request");
                    perStr = perStr.replace("0x99orderCode", paymentOrder.getOrderCode());
                    perStr = perStr.replace("0x99amount", paymentOrder.getYfAmount() + "");
                    perStr = perStr.replace("0x992amount", paymentOrder.getYfAmount().setScale(2) + "");
                    perStr = perStr.replace("0x9914orderTime", dateTime_);

                    perStr = perStr.replace("0x99fenamount", MoneyUtil.changeY2F(paymentOrder.getYfAmount() + ""));
                    perStr = perStr.replace("0x99apiKey", tRealChannelConfig.getApiKey());
                    perStr = perStr.replace("0x99apiMerchant", merchantId);
                    perStr = perStr.replace("0x99notifyurl", pay_notifyurl);

                    perStr = perStr.replace("0x99orderTime", dateTime);
                    perStr = perStr.replace("0x99MillisOrderTime", orderTimeMillis);
                    perStr = perStr.replace("0x9910MillisOrderTime", orderTimeMillis.substring(0, 10));
                    perStr = perStr.replace("0x99merchantOrderCode", paymentOrder.getMerOrderCode());
                    if (StringUtils.isNotBlank(paymentOrder.getClinetIp()))
                        perStr = perStr.replace("0x99clientIp", paymentOrder.getClinetIp());
                    if (StringUtils.isNotBlank(tRealChannelConfig.getServiceCode()))
                        perStr = perStr.replace("0x99servicecode", tRealChannelConfig.getServiceCode());
                    if (StringUtils.isNotBlank(paymentOrder.getCustomerId()))
                        perStr = perStr.replace("0x99customerId", paymentOrder.getCustomerId());
                    if (StringUtils.isNotBlank(paymentOrder.getCustomerName()))
                        perStr = perStr.replace("0x99customerName", paymentOrder.getCustomerName());
                    if (StringUtils.isNotBlank(paymentOrder.getAliUserId()))
                        perStr = perStr.replace("0x99aliUserId", paymentOrder.getAliUserId());
                    logger.info("自定义===>待验签数据:" + perStr);
                    if (signType.equalsIgnoreCase("MD5"))
                        sign = Md5Utils.MD5(perStr);
                    else
                        sign = SHAUtils.SHA1(perStr);
                } else if (tRealChannelConfig.getSignRule().equalsIgnoreCase("nomalByNoKey")) {

                    StringBuilder buf = new StringBuilder("");
                    SignUtils.buildPayParams(buf, signMap, false);
                    String preStr = buf.toString();
                    logger.info("参数排序==>待验签数据:" + preStr);
                    if (signType.equalsIgnoreCase("MD5"))
                        sign = Md5Utils.sign(preStr, "&" + keyValue, "utf-8");
                    else
                        sign = SHAUtils.SHA1(preStr + "&" + keyValue);
                    map.put(signKey, sign);
                } else if (tRealChannelConfig.getSignRule().equalsIgnoreCase("nomalByNoAKey")) {

                    StringBuilder buf = new StringBuilder("");
                    SignUtils.buildPayParams(buf, signMap, false);
                    String preStr = buf.toString();
                    logger.info("参数排序==>待验签数据:" + preStr);
                    if (signType.equalsIgnoreCase("MD5"))
                        sign = Md5Utils.sign(preStr, keyValue, "utf-8");
                    else
                        sign = SHAUtils.SHA1(preStr + keyValue);
                    map.put(signKey, sign);
                } else if (tRealChannelConfig.getSignRule().equalsIgnoreCase("nomalByNoBKey")) {
                    StringBuilder buf = new StringBuilder("");
                    SignUtils.buildPayParams(buf, signMap, false);
                    String preStr = buf.toString();
                    logger.info("参数排序==>待验签数据:" + preStr);
                    if (signType.equalsIgnoreCase("MD5"))
                        sign = Md5Utils.sign(preStr, "", "utf-8");
                    else
                        sign = SHAUtils.SHA1(preStr);
                    map.put(signKey, sign);
                } else if (tRealChannelConfig.getSignRule().equalsIgnoreCase("nomalByNoBOtherKey")) {
                    String otherSignKey = rsCfgObj.getString("otherSignKey");
                    signMap.put(otherSignKey, keyValue);
                    StringBuilder buf = new StringBuilder("");
                    SignUtils.buildPayParams(buf, signMap, false);
                    String preStr = buf.toString();
                    logger.info("参数排序==>待验签数据:" + preStr);
                    if (signType.equalsIgnoreCase("MD5"))
                        sign = Md5Utils.sign(preStr, "", "utf-8");
                    else
                        sign = SHAUtils.SHA1(preStr);
                    map.put(signKey, sign);
                } else if (tRealChannelConfig.getSignRule().equalsIgnoreCase("nomalByOtherKey")) {
                    String otherSignKey = rsCfgObj.getString("otherSignKey");
                    StringBuilder buf = new StringBuilder("");
                    SignUtils.buildPayParams(buf, signMap, false);
                    String preStr = buf.toString();
                    logger.info("参数排序==>待验签数据:" + preStr);
                    if (signType.equalsIgnoreCase("MD5"))
                        sign = Md5Utils.sign(preStr, "&" + otherSignKey + "=" + keyValue, "utf-8");
                    else
                        sign = SHAUtils.SHA1(preStr + "&" + otherSignKey + "=" + keyValue);
                    map.put(signKey, sign);
                }
                 **/
            }
            String result = "";
            logger.info("请求通道网关地址==============:" + AuthorizationURL);
            String requestType = rsCfgObj.getString("requestType");
            String paramType = rsCfgObj.getString("paramType");
//        JSONObject rsCfgObj = JSONObject.parseObject(tRealChannelConfig.getReturnParamCfg());
            boolean isTransfer = false;
            if (StringUtils.isNotBlank(rsCfgObj.getString("isTransfer"))) {
                isTransfer = false;
            }
            if (paramType.equalsIgnoreCase("JSON")) {
                logger.info("代付JSON请求内容：" + JSON.toJSONString(map));
                if (isTransfer) {
                    map.put("reqUrl", rsCfgObj.getString("reqUrl"));
                    result = HttpUtils.sendJsonMessage(JSON.toJSONString(map), new HashMap<>(),AuthorizationURL);
//                result = HttpClientUtil.doHttpPost(AuthorizationURL,JSON.toJSONString(map));
                } else {
//                result = HttpClientUtil.doHttpPost(AuthorizationURL,JSON.toJSONString(map));
                    result = HttpUtils.sendJsonMessage(AuthorizationURL,new HashMap<>(),JSON.toJSONString(map) );
                }
            } else {
                if (isTransfer) {
                    map.put("reqUrl", rsCfgObj.getString("reqUrl"));
                }
                StringBuilder newbuf = new StringBuilder((map.size() + 1) * 10);
                SignUtils.buildPayParams(newbuf, map, false);
                String newStr = newbuf.toString();

                logger.info("请求内容：" + newStr);
                if (requestType.equalsIgnoreCase("get")) {
                    result = HttpUtils.sendGet(AuthorizationURL, newStr,"");
                } else {
                    result = HttpUtils.sendPostRequest(AuthorizationURL, newStr);

                }
            }
            logger.info("订单号:" + orderInfo.getId() + " 返回内容：" + result);
            try {
                JSONObject resultObj = JSONObject.parseObject(result);
                String returnSuccCodeKey = rsCfgObj.getString("returnSuccCodeKey");
                String returnSuccCodeValue = rsCfgObj.getString("returnSuccCodeValue");
                String returnErrorCodeKey = rsCfgObj.getString("returnErrorCodeKey");
                String returnMsgKey = rsCfgObj.getString("returnMsgKey");
                String returnObjKey = rsCfgObj.getString("returnObjKey");
                String rsOrderIdKey = rsCfgObj.getString("rsOrderIdKey");
                String returnPayUrlKey = rsCfgObj.getString("returnPayUrlKey");
                String realAmountKey = rsCfgObj.getString("realAmountKey");
                String isNeedAliUserId = rsCfgObj.getString("isNeedAliUserId");
                String aliUserIdKey = rsCfgObj.getString("aliUserIdKey");
                String rsOrderId = null;
                if (StringUtils.isNotBlank(returnObjKey)) {
                    if (returnObjKey.contains("#")) {
                        String[] returnObjKeys = returnObjKey.split("#");
                        JSONObject dataObj = resultObj;
                        for (int i = 0; i < returnObjKeys.length; i++) {
                            dataObj = dataObj.getJSONObject(returnObjKeys[i]);
                        }
                        if (StringUtils.isNotBlank(rsOrderIdKey)) {
                            rsOrderId = dataObj.getString(rsOrderIdKey);
                        }
                    } else {
                        JSONObject dataObj = resultObj.getJSONObject(returnObjKey);
                        if (StringUtils.isNotBlank(rsOrderIdKey)) {
                            rsOrderId = dataObj.getString(rsOrderIdKey);
                        }
                    }
                } else {
                    if (StringUtils.isNotBlank(rsOrderIdKey)) {
                        rsOrderId = resultObj.getString(rsOrderIdKey);
                    }
                }
                if (StringUtils.isNotBlank(returnSuccCodeKey)) {
                    if (StringUtils.isNotBlank(resultObj.getString(returnSuccCodeKey))) {
                        if (!resultObj.getString(returnSuccCodeKey).equals(returnSuccCodeValue)) {
//                            return ResultWrap.err(LOG, Constss.FALIED, String.valueOf(resultObj.get(returnMsgKey)));
                            jsonObject.put("code","100");
                            jsonObject.put("msg",resultObj.get(returnMsgKey));
                            return jsonObject;
                        }
                    }
                }
                if (StringUtils.isNotBlank(returnErrorCodeKey)) {
                    if (StringUtils.isNotBlank(resultObj.getString(returnErrorCodeKey))) {
                        jsonObject.put("code","100");
                        jsonObject.put("msg",resultObj.get(returnMsgKey));
                        return jsonObject;
                    }
                }
                String url = "";
                String realAmount = null;
                String rsAliUserId = null;
                if (StringUtils.isNotBlank(returnObjKey)) {
                    if (returnObjKey.contains("#")) {
                        String[] returnObjKeys = returnObjKey.split("#");
                        JSONObject dataObj = resultObj;
                        for (int i = 0; i < returnObjKeys.length; i++) {
                            dataObj = dataObj.getJSONObject(returnObjKeys[i]);
                        }
                        url = (String) dataObj.get(returnPayUrlKey);
                        if (StringUtils.isNotBlank(realAmountKey)) {
                            realAmount = dataObj.getString(realAmountKey);
                        }
                        if (StringUtils.isNotBlank(aliUserIdKey)) {
                            rsAliUserId = dataObj.getString(aliUserIdKey);
                        }
                        if (StringUtils.isNotBlank(rsOrderIdKey)) {
                            rsOrderId = dataObj.getString(rsOrderIdKey);
                        }
                    } else {
                        JSONObject dataObj = resultObj.getJSONObject(returnObjKey);
                        url = (String) dataObj.get(returnPayUrlKey);
                        if (StringUtils.isNotBlank(realAmountKey)) {
                            realAmount = dataObj.getString(realAmountKey);
                        }
                        if (StringUtils.isNotBlank(aliUserIdKey)) {
                            rsAliUserId = dataObj.getString(aliUserIdKey);
                        }
                        if (StringUtils.isNotBlank(rsOrderIdKey)) {
                            rsOrderId = dataObj.getString(rsOrderIdKey);
                        }
                    }
                } else {
                    url = (String) resultObj.get(returnPayUrlKey);
                    if (StringUtils.isNotBlank(realAmountKey)) {
                        realAmount = resultObj.getString(realAmountKey);
                    }
                    if (StringUtils.isNotBlank(aliUserIdKey)) {
                        rsAliUserId = resultObj.getString(aliUserIdKey);
                    }
                    if (StringUtils.isNotBlank(rsOrderIdKey)) {
                        rsOrderId = resultObj.getString(rsOrderIdKey);
                    }
                }
                jsonObject.put("payUrl",url);
                jsonObject.put("orderNo",rsOrderId);
                jsonObject.put("code","200");
                return jsonObject;
            } catch (Exception e) {
                logger.info("错误：{}", e.getMessage());
                jsonObject.put("code","100");
                jsonObject.put("msg", "通道异常,请稍后再试！" + e.getMessage());
                return jsonObject;
            }
        } catch (Exception e) {
            logger.info("错误2：{}", e.getMessage());
            jsonObject.put("code","100");
            jsonObject.put("msg", "通道异常,请稍后再试！" + e.getMessage());
            return jsonObject;
        }

    }

    @Override
    public ResponseData smartReissueOrder(TOrderInfo orderInfo) throws Exception {
        return null;
    }


    public JSONObject createWxPayOrder(TOrderInfo orderInfo) throws ServiceException, UnsupportedEncodingException {
        return null;
    }
}
